/*
 ------------------------------------------------------------------------------
 Copyright (C) 2006-2007 Team Blur.

 This file is part of the Quantum Engine source code.

 The Quantum Engine source code is free software; you can redistribute it and/or
 modify it under the terms of the GNU General Public License as published by
 the Free Software Foundation; either version 2 of the License, or (at your
 option) any later version.

 The Quantum Engine source code is distributed in the hope that it will be useful,
 but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
 or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
 more details.

 You should have received a copy of the GNU General Public License along with
 the Quantum Engine source code; if not, write to the Free Software Foundation, Inc.,
 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
 ------------------------------------------------------------------------------
*/


// This file must be identical in the game and utils directories.
// ZIP and OGG file formats are not included here.


#ifndef __FILEFORMATS_H__
#define __FILEFORMATS_H__

/*
 ==============================================================================

 TGA files are used for textures

 ==============================================================================
*/

typedef struct {
	byte			idLength;
	byte			colormapType;
	byte			imageType;
	word			colormapIndex;
	word			colormapLength;
	byte			colormapSize;
	word			xOrigin;
	word			yOrigin;
	word			width;
	word			height;
	byte			pixelSize;
	byte			attributes;
} tgaHeader_t;

/*
 ==============================================================================

 WAV files are used for sounds

 ==============================================================================
*/

typedef struct {
	word			format;
	word			channels;
	dword			samplesPerSec;
	dword			avgBytesPerSec;
	word			blockAlign;
	word			bitsPerSample;
} wavHeader_t;

/*
 ==============================================================================

 RoQ files are used for videos

 ==============================================================================
*/

#define ROQ_IDENT					0x1084

#define ROQ_QUAD_INFO				0x1001
#define ROQ_QUAD_CODEBOOK			0x1002
#define ROQ_QUAD_VQ					0x1011
#define ROQ_SOUND_MONO				0x1020
#define ROQ_SOUND_STEREO			0x1021

#define ROQ_CHUNK_HEADER_SIZE		8			// Size of a RoQ chunk header

#define ROQ_MAX_CHUNK_SIZE			65536		// Max size of a RoQ chunk

typedef struct {
	word			id;
	dword			size;
	word			flags;
} roqChunk_t;

typedef struct {
	dword			pixel[4];
} roqQuadVector_t;

typedef struct {
	byte			index[4];
} roqQuadCell_t;

/*
 ==============================================================================

 MDL files are used for static render models

 ==============================================================================
*/

#define MDL_IDENT					((' '<<24) + ('L'<<16) + ('D'<<8) + 'M')
#define MDL_VERSION					4

#define MDL_MAX_MESHES				32			// Per model
#define MDL_MAX_VERTICES			4096		// Per mesh
#define MDL_MAX_TRIANGLES			8192		// Per mesh

typedef struct {
	float			xyz[3];
	float			normal[3];
	float			tangents[2][3];
	float			st[2];
	byte			color[4];
} mdlVertex_t;

typedef struct {
	int				indices[3];
	int				neighbors[3];
} mdlTriangle_t;

typedef struct {
	float			normal[3];
	float			dist;
} mdlPlane_t;

typedef struct {
	char			material[256];

	float			bounds[2][3];

	int				numVertices;
	int				ofsVertices;				// Offset from start of mdlMesh_t

	int				numTriangles;
	int				ofsTriangles;				// Offset from start of mdlMesh_t

	int				ofsFacePlanes;				// Offset from start of mdlMesh_t

	int				ofsEnd;						// Next mesh follows
} mdlMesh_t;

typedef struct {
	int				ident;
	int				version;

	float			bounds[2][3];

	int				numMeshes;
	int				ofsMeshes;					// First mesh, others follow
} mdlHeader_t;

/*
 ==============================================================================

 CM files are used for static clip models

 ==============================================================================
*/

#define CM_IDENT					((' '<<24) + (' '<<16) + ('M'<<8) + 'C')
#define CM_VERSION					4

#define CM_MAX_MESHES				32			// Per model
#define CM_MAX_PLANES				16384		// Per mesh
#define CM_MAX_FACETS				2048		// Per mesh

typedef struct {
	float			normal[3];
	float			dist;
} cmPlane_t;

typedef struct {
	int				facetPlane;

	int				numBorders;					// 3 + 6 axial bevels + 3 * 4 edge bevels
	int				borderInward;				// Bit vector
	short			borderPlanes[21];
} cmFacet_t;

typedef struct {
	char			material[256];

	int				surfaceFlags;
	int				contentFlags;

	float			bounds[2][3];

	int				numPlanes;
	int				ofsPlanes;					// Offset from start of cmMesh_t

	int				numFacets;
	int				ofsFacets;					// Offset from start of cmMesh_t

	int				ofsEnd;						// Next mesh follows
} cmMesh_t;

typedef struct {
	int				ident;
	int				version;

	float			bounds[2][3];

	int				numMeshes;
	int				ofsMeshes;					// First mesh, others follow
} cmHeader_t;

/*
 ==============================================================================

 BSP files are used for maps

 ==============================================================================
*/

#define BSP_IDENT					((' '<<24) + ('P'<<16) + ('S'<<8) + 'B')
#define BSP_VERSION					63

#define	BSP_MAX_MATERIALS			0x000400
#define	BSP_MAX_PLANES				0x040000
#define	BSP_MAX_INDICES				0x200000
#define	BSP_MAX_VERTICES			0x080000
#define BSP_MAX_NEIGHBORS			0x200000
#define BSP_MAX_FACEPLANES			0x080000
#define BSP_MAX_FOLIAGEINSTANCES	0x080000
#define	BSP_MAX_BRUSHSIDES			0x080000
#define	BSP_MAX_BRUSHES				0x010000
#define BSP_MAX_SURFACEPLANES		0x100000
#define BSP_MAX_SURFACEFACETS		0x020000
#define	BSP_MAX_SURFACES			0x020000
#define	BSP_MAX_LEAFBRUSHES 		0x080000
#define	BSP_MAX_LEAFSURFACES		0x100000
#define	BSP_MAX_LEAFS				0x010000
#define	BSP_MAX_NODES				0x010000
#define	BSP_MAX_INLINEMODELS		0x000400
#define BSP_MAX_PVS					0x400000
#define BSP_MAX_PORTALS				0x000100
#define BSP_MAX_AREAPORTALS			0x000800
#define	BSP_MAX_AREAS				0x000100

#define LUMP_MATERIALS				0
#define LUMP_PLANES					1
#define LUMP_INDICES				2
#define LUMP_VERTICES				3
#define LUMP_NEIGHBORS				4
#define LUMP_FACEPLANES				5
#define LUMP_FOLIAGEINSTANCES		6
#define LUMP_BRUSHSIDES				7
#define LUMP_BRUSHES				8
#define LUMP_SURFACEPLANES			9
#define LUMP_SURFACEFACETS			10
#define LUMP_SURFACES				11
#define LUMP_LEAFBRUSHES			12
#define LUMP_LEAFSURFACES			13
#define LUMP_LEAFS					14
#define LUMP_NODES					15
#define LUMP_INLINEMODELS			16
#define LUMP_PVS					17
#define LUMP_PORTALS				18
#define LUMP_AREAPORTALS			19
#define LUMP_AREAS					20
#define HEADER_LUMPS				21

typedef enum {
	ST_BAD,
	ST_FACE,
	ST_PATCH,
	ST_TRISOUP,
	ST_FOLIAGE
} surfaceType_t;

typedef struct {
	int				offset;
	int				length;
} bspLump_t;

typedef struct {
	int				id;
	int				version;

	bspLump_t		lumps[HEADER_LUMPS];
} bspHeader_t;

typedef struct {
	char			name[256];

	int				surfaceFlags;
	int				contentFlags;
} bspMaterial_t;

typedef struct {
	float			normal[3];
	float			dist;
} bspPlane_t;

typedef struct {
	float			xyz[3];
	float			normal[3];
	float			tangents[2][3];
	float			st[2];
	byte			color[4];
} bspVertex_t;

typedef struct {
	float			origin[3];
	float			angles[3];
} bspFoliageInstance_t;

typedef struct {
	int				materialNum;				// The material that determines the surface flags

	int				planeNum;
} bspBrushSide_t;

typedef struct {
	int				materialNum;				// The material that determines the content flags

	int				numSides;
	int				firstSide;
} bspBrush_t;

typedef struct {
	int				facetPlane;

	int				numBorders;					// 3 or 4 + 6 axial bevels + 3 or 4 * 4 edge bevels
	int				borderInward;				// Bit vector
	short			borderPlanes[26];
} bspSurfaceFacet_t;

typedef struct {
	surfaceType_t	type;

	int				materialNum;
	int				planeNum;

	float			bounds[2][3];

	// Collision information
	int				numPlanes;
	int				firstPlane;

	int				numFacets;
	int				firstFacet;

	// Rendering information
	int				numIndices;
	int				firstIndex;

	int				numVertices;
	int				firstVertex;

	int				firstNeighbor;
	int				firstFacePlane;

	int				numFoliageInstances;
	int				firstFoliageInstance;

	float			foliageRadius;
	float			foliageMinDistance;
	float			foliageMaxDistance;
} bspSurface_t;

typedef struct {
	int				cluster;					// -1 == opaque cluster
	int				area;						// -1 == opaque area

	int				canSeePortalSky;			// For server side culling of portal sky entities

	int				bounds[2][3];

	int				numLeafBrushes;
	int				firstLeafBrush;

	int				numLeafSurfaces;
	int				firstLeafSurface;
} bspLeaf_t;

typedef struct {
	int				planeNum;
	int				children[2];				// Negative numbers are leafs, not nodes

	int				bounds[2][3];
} bspNode_t;

typedef struct {
	float			bounds[2][3];

	int				numBrushes;
	int				firstBrush;

	int				numSurfaces;
	int				firstSurface;
} bspInlineModel_t;

typedef struct {
	int				portalNum;					// Area portal brush
	int				areas[2];					// Areas connected by the portal
} bspPortal_t;

typedef struct {
	int				numAreaPortals;
	int				firstAreaPortal;
} bspArea_t;


#endif	// __FILEFORMATS_H__
